/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package BL;

/**
 *
 * @author Elessar
 */
import BE.*;
import java.util.List;
import java.util.ArrayList;

/**
 *
 * @author Elessar
 */
public class BLTwoOptDespacho {
    
    BLGrafoAlmacen blGrafoAlmacen;
    int cantNodos;
    
    public  BLTwoOptDespacho (BLGrafoAlmacen blGrafoAlmacen)
    {
        this.blGrafoAlmacen=blGrafoAlmacen;        
    }
    
    public ArrayList<BENodoDespacho> run (ArrayList<BENodoDespacho> SolucionInicial)
    {
        //SolucionInicial.add(0,new BENodoDespacho(0,0,0,0,0,1,1,1,0));
        //SolucionInicial.add(new BENodoDespacho(0,0,0,0,0,1,1,1,0));
        //SolucionInicial.remove(0);
        
        for (int i=1; i<SolucionInicial.size()-1; i++)
            for (int j=i+2; j<SolucionInicial.size(); j++){
//                int dist = getDistancia(SolucionInicial.get(i),SolucionInicial.get(j));
//                if (dist==0){
                if (SolucionInicial.get(i).getX()==SolucionInicial.get(j).getX() 
                        && SolucionInicial.get(i).getY()==SolucionInicial.get(j).getY()){
                    BENodoDespacho nodoAux = SolucionInicial.get(j);
                    SolucionInicial.remove(j);
                    SolucionInicial.add(i,nodoAux);
                }
            }
        System.out.println("Primer filtro");
        
        for (int i=1; i<SolucionInicial.size()-1; i++){            
            while(SolucionInicial.get(i).getX()==SolucionInicial.get(i+1).getX() 
                        && SolucionInicial.get(i).getY()==SolucionInicial.get(i+1).getY()
                        && i+1<SolucionInicial.size()-1){
                if (SolucionInicial.get(i).getZ()>SolucionInicial.get(i+1).getZ()){
                    BENodoDespacho nodoAux = SolucionInicial.get(i+1);
                    SolucionInicial.set(i+1, SolucionInicial.get(i));
                    SolucionInicial.set(i, nodoAux);
                }
                i++;
            }
        }
        System.out.println("Segundo filtro");
        
        return SolucionInicial;
        
//        cantNodos = SolucionInicial.size();
//        List<BEArco> listaArcos = getListaArcos(SolucionInicial);
//        System.out.println("Arcos antes de ordenar:");
//        for (int i=0; i<listaArcos.size(); i++){
//            System.out.println("--Arco: Nodo1:"+listaArcos.get(i).getNodo1().getIdNodo()+" Nodo2:"+listaArcos.get(i).getNodo2().getIdNodo()+" Dist:"+listaArcos.get(i).getDistancia());
//        }
//
//        listaArcos = ordenar(listaArcos);
//        System.out.println("Arcos despues de ordenar:");
//        for (int i=0; i<listaArcos.size(); i++){
//            System.out.println("--Arco: Nodo1:"+listaArcos.get(i).getNodo1().getIdNodo()+" Nodo2:"+listaArcos.get(i).getNodo2().getIdNodo()+" Dist:"+listaArcos.get(i).getDistancia());
//        }
//
//        
//        for (int p = 0; p < cantNodos; p++)
//        {
//            BEArco maxArco = listaArcos.get(0);
//            BENodoDespacho i, j, l, k;
//            double dist_ij, dist_lk, dist_il, dist_jk;
//            
//            i= maxArco.getNodo1();
//            j= maxArco.getNodo2();
//            dist_ij = maxArco.getDistancia();
//            
//            for (int q = 1; q < listaArcos.size(); q++)
//            {
//                l= listaArcos.get(q).getNodo1();
//                k= listaArcos.get(q).getNodo2();
//                dist_lk = listaArcos.get(q).getDistancia();
//                
//                //Se evalua la nueva solucion
//                dist_il = getDistancia(i,l);
//                dist_jk = getDistancia(j,k);
//                //Se comparan los costos (distancias)                
//                if (dist_ij+dist_lk > dist_il+dist_jk && dist_il!=0 && dist_jk!=0)
//                {
////                    int m;
////                    for (m=0;m<listaArcos.size();m++)
////                        if (listaArcos.get(m).getIdNodoHijo().equals(i+" "+j))
////                            break;
////                    listaArcos.remove(m);
////                    
////                    for (m=0;m<listaArcos.size();m++)
////                        if (listaArcos.get(m).getIdNodoHijo().equals(l+" "+k))
////                            break;
////                    listaArcos.remove(m);
//                    listaArcos.remove(0);
//                    listaArcos.remove(q-1);
//                    
//                    BEArco arcoXY = new BEArco(i,l,dist_il);                    
//                    listaArcos.add(arcoXY);
//                    
//                    arcoXY = new BEArco(j,k,dist_jk);
//                    listaArcos.add(arcoXY);
//                    //deleteListaArcos(i+" "+j);
//                    //deleteListaArcos(l+" "+k);
//                    //insertListaArcos(i+" "+l,dist_il);
//                    //insertListaArcos(j+" "+k,dist_jk);
//                    ordenar(listaArcos);
//                    break;
//                }
//            }
//        }
//        System.out.println("Termina TwoOpt");
//        System.out.println("Arcos despues de 2opt:");
//        for (int i=0; i<listaArcos.size(); i++){
//            System.out.println("--Arco: Nodo1:"+listaArcos.get(i).getNodo1().getIdNodo()+" Nodo2:"+listaArcos.get(i).getNodo2().getIdNodo()+" Dist:"+listaArcos.get(i).getDistancia());
//        }
//        //return listaArcos;
//        //return presentarRuta(listaArcos);
//        return ordenarNodosFinal(listaArcos);
    }
    
    public List<BEArco> getListaArcos(List<BENodoDespacho> SolucionInicial)
    {
        List<BEArco> listaArcos = new ArrayList<BEArco>();
        //BENodo nodo = null;
        BEArco arco=null;
        BENodoDespacho nodoA;
        BENodoDespacho nodoB;
        double distancia = 0;

        for (int i=0;i<SolucionInicial.size()-1;i++)
        {
                nodoA = SolucionInicial.get(i);
                nodoB = SolucionInicial.get(i+1);
                //distancia = SolucionInicial.get(i+1).getDist();
                distancia = getDistancia(nodoA,nodoB);
                arco = new BEArco(nodoA,nodoB,distancia);
                listaArcos.add(arco);
        }
        
        
        return listaArcos;
    }
    
    public int getDistancia (BENodoDespacho nodo1, BENodoDespacho nodo2){
//        return Math.sqrt(Math.pow(nodo1.getX()*1.0-nodo2.getX()*1.0,2.0)
//                +Math.pow(nodo1.getY()*1.0-nodo2.getY()*1.0,2.0));
        BENodo nAux1 = new BENodo(blGrafoAlmacen.getIdNodoXY(nodo1.getX(),nodo1.getY()),nodo1.getX(),nodo1.getY());
        BENodo nAux2 = new BENodo(blGrafoAlmacen.getIdNodoXY(nodo2.getX(),nodo2.getY()),nodo2.getX(),nodo2.getY());
        return blGrafoAlmacen.generarRutaParcial(nAux1, nAux2).size();
    }
    
    public static List<BEArco> ordenar (List<BEArco> arcos)
    {
        BEArco arcoAux = null;
        
        for (int i=0;i<arcos.size()-1;i++)
            for(int j=1;j<arcos.size();j++)
                if (arcos.get(i).getDistancia()<arcos.get(j).getDistancia())
                {
                    arcoAux = arcos.get(i);
                    arcos.set(i, arcos.get(j));
                    arcos.set(j, arcoAux);
                }
        return arcos;
    }
    
   
    public static int getDistanciaGrafo (List<BENodo> grafo, int nodo1, int nodo2)
    {
        int distancia=0;
        for (int i=0; i<grafo.size(); i++)
        {
            if (grafo.get(i).getIdNodo()==nodo1)
            {
                for (int j=0; j<grafo.get(i).getVecinos().size(); j++)
                    if (grafo.get(i).getVecinos().get(j).getIdNodo()==nodo2)
                    {
                        distancia=grafo.get(i).getVecinos().get(j).getDist();
                        break;
                    }
                break;
            }
        }
        return distancia;
    }
    
    public static ArrayList<BENodoDespacho> presentarRuta (List<BEArco> listaArcos)
    {
        ArrayList<BENodoDespacho> rutaFinal = new ArrayList<BENodoDespacho>();
        //double distanciaSig=0;
        for (int i=0; i<listaArcos.size(); i++)
        {
            //BENodoDespacho nodoAux = new BENodoDespacho();
            //String [] auxStr = listaArcos.get(i).getIdNodoHijo().split(" ");
//            nodoAux.setIdNodo(listaArcos.get(i).getNodo1());
//            nodoAux.setDist(distanciaSig);
//            distanciaSig=listaArcos.get(i).getDistancia();
            BENodoDespacho nodoAux = listaArcos.get(i).getNodo1();
            rutaFinal.add(nodoAux);
            if (i==listaArcos.size()-1) 
            {
//                BENodo nodoAux2 = new BENodo();
//                nodoAux2.setIdNodo(listaArcos.get(i).getNodo2());
//                nodoAux2.setDist(distanciaSig);
                BENodoDespacho nodoAux2 = listaArcos.get(i).getNodo2();
                rutaFinal.add(nodoAux2);
            }
        }
        //rutaFinal.remove(0);
        //rutaFinal.remove(rutaFinal.size()-1);
        return rutaFinal;
    }
    
    public ArrayList<BENodoDespacho> ordenarNodosFinal(List<BEArco> listaArcos){
        ArrayList<BENodoDespacho> rutaFinal = new ArrayList<BENodoDespacho>();
        int cont=0;
        boolean encontrado1=false, encontrado2=false;
        System.out.println("Presentacion final de Nodos:");
        for (int i=0; i<listaArcos.size(); i++){
            if (listaArcos.get(i).getNodo1().getIdNodo()==0 || listaArcos.get(i).getNodo2().getIdNodo()==0){
                if (listaArcos.get(i).getNodo1().getIdNodo()==0){ 
                    rutaFinal.add(listaArcos.get(i).getNodo1());
                    System.out.println("---Nodo1:"+listaArcos.get(i).getNodo1().getIdNodo());
                    rutaFinal.add(listaArcos.get(i).getNodo2());
                    System.out.println("---Nodo2:"+listaArcos.get(i).getNodo2().getIdNodo());
                    cont+=2;
                    int idnodoAux = listaArcos.get(i).getNodo2().getIdNodo();
                    while (cont<cantNodos){
                        if (!encontrado2){
                            for (int j=0; j<listaArcos.size(); j++){
                                encontrado1=false;
                                if (listaArcos.get(j).getNodo1().getIdNodo()==idnodoAux){
                                    rutaFinal.add(listaArcos.get(j).getNodo2());
                                    System.out.println("---Nodo2:"+listaArcos.get(j).getNodo2().getIdNodo());
                                    idnodoAux=listaArcos.get(j).getNodo2().getIdNodo();
                                    cont++;
                                    encontrado1=true;
                                    encontrado2=false;
                                    listaArcos.remove(j);
                                    break;
                                }
                            }
                            if (!encontrado1) encontrado2=true;
                        }
                        if (!encontrado1){
                            for (int j=0; j<listaArcos.size(); j++){
                                encontrado2=false;
                                if (listaArcos.get(j).getNodo2().getIdNodo()==idnodoAux){
                                    rutaFinal.add(listaArcos.get(j).getNodo1());
                                    System.out.println("---Nodo1:"+listaArcos.get(j).getNodo1().getIdNodo());
                                    idnodoAux=listaArcos.get(j).getNodo1().getIdNodo();
                                    cont++;
                                    encontrado2=true;
                                    encontrado1=false;
                                    listaArcos.remove(j);
                                    break;
                                }
                            }
                            if (!encontrado2) encontrado1=true;
                        }
                    }
                }
                else if (listaArcos.get(i).getNodo2().getIdNodo()==0) {
                    rutaFinal.add(listaArcos.get(i).getNodo2());
                    System.out.println("TwoOpt trolling");
                }
                
                break;
            }
        }
        
        return rutaFinal;
    }
}
